#ifndef VISUALIZATION_H_INCLUDED
#define	VISUALIZATION_H_INCLUDED
#include <string>
#include <vector>

#include "Vector.h"
#include <rfftw.h>              //the numerical simulation FFTW library
#include "ColorLegend.h"
#include "ColorMap.h"

class Simulation;

class Visualization
{
	friend class Application;
    
    ColorLegend d_legend_scalar;
    ColorLegend d_legend_vector;
    ColorMap d_map_scalar;
    ColorMap d_map_vector;
        
    public:

        Visualization();
        void visualize(Simulation const &simulation, int winWidth, int winHeight);

        //different types of color mapping: black-and-white, rainbow, banded
        enum ColorMode
        {
                BlackWhite,		
                Rainbow,
                Ocean,
                CustomHue,
                ColorModeCount				// (automatically assigned)
        };

        enum VectorDataSet
        {
            FluidVelocity,
            ForceField,
            VectorDataSetCount
        };

        enum Dataset
        {
            Density,
            Velocity,
            Force,
            DataSetCount
        };
        
        enum GlyphType
        {
            Hedgehog,
            Triangle,
            GlyphTypeCount
        };

        enum Option
        {
                DrawSmoke,				// draw the smoke or not
                DrawVectorField,		// draw the vector field or not
                UseDirectionColoring,	// use direction color-coding or not
                UseLogScaling,              //Use log when scaling
                OptionsCount			// (automatically assigned)
        };

        void toggle(Option option);
        void enable(Option option);
        void disable(Option option);
        bool is_enabled(Option option) const;		
        void set_hedgehog_scale(float scale);
        void scale_hedgehogs(float scale);
        float hedgehog_scale() const;
        
        void setGlyphType(int g);
        void setColorMode(int colorMode);
        void setDataSet(int dataSet);
        void setVectorDataSet(int vectorDataSet);
        void setScaleMode(int scaleMode);
        void setLevels(int l);
        void setHue(double h);
        void setSat(double s);
        void setVal(double v);
        
        void setMin(double m);
        void setMax(double m);
        
        float getVecScale();
        
        double getHue();
        double getSat();
        double getVal();
        int getLevels();
        int getColorMode();
        int getScaleMode();

        bool isHConst();
        bool isSConst();
        bool isVConst();
        
        
        //vector color map acessors/manipulatosr
        void setColorModeVec(int colorMode);        
        void setScaleModeVec(int scaleMode);
        void setLevelsVec(int l);
        void setHueVec(double h);
        void setSatVec(double s);
        void setValVec(double v);
        
        void setMinVec(double m);
        void setMaxVec(double m);
        
        double getHueVec();
        double getSatVec();
        double getValVec();
        int getLevelsVec();
        int getColorModeVec();
        int getScaleModeVec();

        bool isHConstVec();
        bool isSConstVec();
        bool isVConstVec();
        
//      void rainbow(float value, float* R, float* G, float* B);
        void set_colormap(float vy);

        void direction_to_color(float x, float y, int method);
		
	private:
            void drawGlyph(Vector2f v, float gx, float gy);
            float get_datapoint(Simulation const &simulation, int idx);
            float get_vector_x(Simulation const &simulation, int idx); 
            float get_vector_y(Simulation const &simulation, int idx);
            Vector2f get_vector(Simulation const &simulation, int idx);
            float getMin(Simulation const &simulation);
            float getMax(Simulation const &simulation);
            float vectorScaleFactor(Vector2f v);
            float vec_scale;				// scaling of hedgehogs 
            int options[OptionsCount];		// options boolean array                
            int scalar_col;			//method for scalar coloring
            std::vector<std::string> colormodes;
            std::vector<std::string> datasets;
            std::vector<std::string> vectordatasets;
            std::vector<std::string> glyphtypes;
            Dataset d_dataset;
            VectorDataSet d_vector_dataset;
            GlyphType d_glyphtype;
        
};

inline void Visualization::setGlyphType(int g)
{
    d_glyphtype = (GlyphType) g;
}

inline void Visualization::setLevels(int l)
{
    d_map_scalar.levels(l);
}

inline void Visualization::setVal(double v)
{
    d_map_scalar.value(v);
}

inline void Visualization::setHue(double s)
{
    d_map_scalar.hue(s);
}

inline void Visualization::setSat(double s)
{
    d_map_scalar.saturation(s);
}

inline void Visualization::setMax(double m)
{
    d_map_scalar.clampMax(m);
}

inline void Visualization::setMin(double m)
{
    d_map_scalar.clampMin(m);
}

inline float Visualization::getVecScale() 
{
    return vec_scale;
}

inline double Visualization::getHue()
{
    return d_map_scalar.hue();
}

inline double Visualization::getSat()
{
    return d_map_scalar.saturation();
}

inline double Visualization::getVal()
{
    return d_map_scalar.value();
}

inline int Visualization::getColorMode()
{
    return int(d_map_scalar.colorMode());
}

inline int Visualization::getScaleMode()
{
    return int(d_map_scalar.scaleMode());
}

inline int Visualization::getLevels()
{
    return d_map_scalar.levels();
}

inline bool Visualization::isHConst()
{
    return d_map_scalar.constH();
}

inline bool Visualization::isSConst()
{
    return d_map_scalar.constS();
}

inline bool Visualization::isVConst()
{
    return d_map_scalar.constV();
}

inline void Visualization::setLevelsVec(int l)
{
    d_map_vector.levels(l);
}

inline void Visualization::setValVec(double v)
{
    d_map_vector.value(v);
}

inline void Visualization::setHueVec(double s)
{
    d_map_vector.hue(s);
}

inline void Visualization::setSatVec(double s)
{
    d_map_vector.saturation(s);
}

inline void Visualization::setMaxVec(double m)
{
    d_map_vector.clampMax(m);
}

inline void Visualization::setMinVec(double m)
{
    d_map_vector.clampMin(m);
}

inline double Visualization::getHueVec()
{
    return d_map_vector.hue();
}

inline double Visualization::getSatVec()
{
    return d_map_vector.saturation();
}

inline double Visualization::getValVec()
{
    return d_map_vector.value();
}

inline int Visualization::getColorModeVec()
{
    return int(d_map_vector.colorMode());
}

inline int Visualization::getScaleModeVec()
{
    return int(d_map_vector.scaleMode());
}

inline int Visualization::getLevelsVec()
{
    return d_map_vector.levels();
}

inline bool Visualization::isHConstVec()
{
    return d_map_vector.constH();
}

inline bool Visualization::isSConstVec()
{
    return d_map_vector.constS();
}

inline bool Visualization::isVConstVec()
{
    return d_map_vector.constV();
}




#endif
